home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
games
/
sakiba
/
source
/
main.c
< prev
next >
Wrap
Text File
|
2000-06-23
|
13KB
|
540 lines
/*********************************************
格闘シミュレーション「さきば」
メイン
*********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys\iocs.h>
#include <sys\dos.h>
#include "sakiba.h"
#include "screen.h"
#include "chranim.h"
#include "select.h"
#include "pad.h"
#include "sound.h"
CHR_PARAM chr_param[2]; /* キャラクタパラメータ */
int turn; /* ターン */
int mode; /* モード */
static Bool watch; /* 観戦モード */
/*******************************************
キャラクタシーケンス設定
引数 chr = キャラクタ
seq1 = シーケンス(本体)
seq2 = シーケンス(サブ)
num = シーケンス番号
*******************************************/
static
void chr_sequence(CHR_PARAM* chr, SEQUENCE* seq1, SEQUENCE* seq2)
{
set_sequence(&chr->spr[0], seq1->pat ? seq1 : NULL); /* 本体 */
set_sequence(&chr->spr[1], seq2->pat ? seq2 : NULL); /* サブ */
}
static
void chr_sequence2(CHR_PARAM* chr, int num)
{
chr_sequence(chr, &chr->data->seq[num][0], &chr->data->seq[num][1]);
}
/*******************************************
キャラクタ初期化
引数 chr = パラメータバッファ
num = プレイヤー番号
opr = 操作
data = キャラクタデータ
*******************************************/
void init_chr(CHR_PARAM* chr, int num, int opr, CHR_DATA* data)
{
ACTION* p;
int i;
chr->num = num; /* プレイヤー番号 */
chr->operation = opr; /* 操作 */
chr->data = data; /* データ */
load_chr(chr); /* キャラクタスプライト読み込み */
chr->hit_point = chr->d_hp = HP_MAX; /* 体力 */
for (i = 0, p = chr->action; i < 6; i++, p++) { /* 行動 */
switch ( i ) {
case 0 : /* 構える前 */
p->kind = ACT_SUKI;
p->count = (num == PLAYER1) ? (rnd(3) + 1) : (rnd(2) + 1);
break;
case 1 : /* 防御 */
p->kind = ACT_GUARD;
p->count = GUARD_CNT;
break;
default : /* 未定 */
p->kind = -1;
break;
}
}
}
/**************************************
キャラクタアニメを進める
引数 num = プレイヤー番号
戻り値 アニメーション終端か
**************************************/
static
Bool anim_chr(int num)
{
anim_spr(&chr_param[num].spr[1]); /* サブ */
return anim_spr(&chr_param[num].spr[0]); /* 本体 */
}
/******************************
キャラクタ登場
戻り値 TRUE : 続行
FALSE : 終了
******************************/
static
Bool ready_chr(void)
{
int i;
mode = MODE_READY; /* 登場モード */
chr_sequence2(&chr_param[PLAYER1], SEQ_READY); /* 登場シーケンス */
chr_sequence2(&chr_param[PLAYER2], SEQ_READY);
for (i = 0; i < 250; i++) {
anim_chr(PLAYER1); /* キャラクタアニメーション */
anim_chr(PLAYER2);
draw_screen(); /* 画面描画 */
if ( esc_key ) { /* ゲーム終了 */
return FALSE;
}
if ( i == 100 ) { /* 構え */
chr_sequence2(&chr_param[PLAYER1], SEQ_NORMAL);
chr_sequence2(&chr_param[PLAYER2], SEQ_NORMAL);
}
else if ( i == 130 ) {
set_message(MES_READY); /* Ready */
}
else if ( i == 200 ) {
set_message(MES_FIGHT); /* Fight */
}
}
set_message(-1); /* メッセージ消去 */
return TRUE;
}
/************************************
戦闘終了
引数 win = 勝利者
戻り値 TRUE : ゲーム続行
FALSE : ゲーム終了
************************************/
static
Bool end_battle(int win)
{
int i;
set_message((win == PLAYER1) ? MES_1P : MES_2P); /* Win */
fadeout_music(); /* BGMフェードアウト */
for (i = 0; i < 370; i++) {
anim_chr(PLAYER1); /* キャラクタアニメーション */
anim_chr(PLAYER2);
draw_screen(); /* 画面描画 */
if ( esc_key ) { /* ゲーム終了 */
return FALSE;
}
if ( (i < 250) && ((get_push(0) & PAD_A) || (get_push(1) & PAD_A)) ) {
i = 250;
}
if ( i == 250 ) {
_iocs_contrast(0); /* フェードアウト */
}
}
return TRUE;
}
/*****************************
行動の繰り上げ
引数 act = 行動
*****************************/
static
void move_up(ACTION* act)
{
int i;
for (i = 0; i < 6 - 1; i++) {
*act = *(act + 1);
act++;
}
act->kind = -1;
}
/**********************
COM思考
戻り値 行動
**********************/
static
int com_action(void)
{
ACTION *o_act, *d_act;
int t;
o_act = chr_param[turn].action; /* 自分の行動 */
d_act = chr_param[turn ^ 0x01].action; /* 相手の行動 */
if ( o_act[0].kind == ACT_GUARD ) {
t = o_act[0].count - d_act[0].count;
if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
if ( o_act[0].count < d_act[0].count ) {
return ACT_GUARD;
}
t -= d_act[1].count;
}
}
else {
if ( o_act[0].count < d_act[0].count ) {
if ( d_act[0].kind == ACT_GUARD ) {
t = o_act[0].count + o_act[1].count - d_act[0].count;
}
else {
t = o_act[1].count - DAMAGE_CNT;
}
}
else if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
t = DAMAGE_CNT - d_act[1].count;
}
else {
t = o_act[0].count + o_act[1].count - d_act[0].count;
}
}
if ( t > 0 ) {
if ( rnd(9 + t) > 8 ) {
return ACT_ATTACK2;
}
if ( rnd(8 + t) > 6 ) {
return ACT_ATTACK1;
}
return ACT_GUARD;
}
else {
if ( rnd(7 - t) < 2 ) {
return ACT_GUARD;
}
if ( rnd(6 - t) > 4 ) {
return ACT_ATTACK2;
}
return ACT_ATTACK1;
}
}
/***********************************
行動入力
引数 chr = キャラクタ
戻り値 行動
-1 : ゲーム終了
***********************************/
static
int input_action(CHR_PARAM* chr)
{
PAD pad;
mode = MODE_INPUT; /* 入力モード */
while ( 1 ) {
anim_chr(chr->num ^ 0x01); /* キャラクタアニメーション */
draw_screen(); /* 画面描画 */
pad = get_push(chr->num); /* 入力 */
if ( esc_key ) {
return -1; /* ゲーム終了 */
}
if ( pad & PAD_LEFT ) {
return (chr->num == PLAYER1) ? ACT_GUARD : ACT_ATTACK1;
}
if ( pad & PAD_RIGHT ) {
return (chr->num == PLAYER1) ? ACT_ATTACK1 : ACT_GUARD;
}
if ( pad & PAD_UP ) {
return ACT_ATTACK2;
}
}
}
/**********************************
行動選択
引数 chr = キャラクタ
戻り値 TRUE : 続行
FALSE : 終了
**********************************/
static
Bool select_action(CHR_PARAM* chr)
{
ACTION* act;
int n;
act = chr->action; /* 行動 */
while ( act->kind >= 0 ) { /* 空き検索 */
act++;
}
act->kind = -1;
n = (chr->operation == OPR_PLAYER) ? input_action(chr) : com_action();
/* 行動入力 */
switch ( n ) {
case ACT_GUARD : /* 防御 */
act->kind = ACT_GUARD;
act->count = GUARD_CNT;
break;
case ACT_ATTACK1 : /* 弱攻撃 */
act->kind = ACT_ATTACK1;
act->count = chr->data->attack1.before;
act++;
act->kind = ACT_SUKI;
act->count = chr->data->attack1.after;
break;
case ACT_ATTACK2 : /* 強攻撃 */
act->kind = ACT_ATTACK2;
act->count = chr->data->attack2.before;
act++;
act->kind = ACT_SUKI;
act->count = chr->data->attack2.after;
break;
default : /* ゲーム終了 */
return FALSE;
}
return TRUE;
}
/*******************************************
行動アニメーション再生
引数 slow = スローモーションか
*******************************************/
static
void play_action(Bool slow)
{
Bool loop = TRUE;
while ( loop ) {
if ( anim_chr(PLAYER1) && (turn == PLAYER1) ) {
loop = FALSE;
}
if ( anim_chr(PLAYER2) && (turn == PLAYER2) ) {
loop = FALSE;
}
draw_screen(); /* 画面描画 */
if ( slow ) {
draw_screen();
}
if ( esc_key ) {
return;
}
}
}
/********************************
攻撃
引数 atk = 攻撃技
戻り値 決着がついたか
********************************/
static
Bool attack(ATK_TECH* atk)
{
CHR_PARAM *o_chr, *d_chr;
ACTION *d_act;
o_chr = &chr_param[turn]; /* 攻撃側 */
d_chr = &chr_param[turn ^ 0x01]; /* 守備側 */
d_act = d_chr->action;
chr_sequence(o_chr, &atk->seq1[0], &atk->seq1[1]); /* 攻撃前シーケンス設定 */
if ( d_act[0].kind == ACT_GUARD ) { /* 防御 */
chr_sequence2(d_chr, SEQ_GUARD); /* 防御シーケンス設定 */
}
play_action(FALSE); /* アニメーション再生 */
if ( d_act[0].kind == ACT_GUARD ) { /* 防御 */
d_chr->hit_point -= atk->power/2;
}
else { /* ヒット */
if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
d_act[1].count += d_act[0].count;
move_up(d_act);
}
d_act[0].kind = ACT_DAMAGE; /* くらい */
d_act[0].count = DAMAGE_CNT;
d_chr->hit_point -= atk->power;
chr_sequence2(d_chr, SEQ_DAMAGE); /* くらいシーケンス設定 */
set_hitmark(); /* ヒットマーク設定 */
}
if ( d_chr->hit_point <= 0 ) {
d_chr->hit_point = 0;
set_message(MES_KO); /* K.O. */
}
slow_bar(FALSE);
chr_sequence(o_chr, &atk->seq2[0], &atk->seq2[1]); /* 攻撃後シーケンス設定 */
if ( d_chr->hit_point == 0 ) { /* 決着 */
play_action(TRUE); /* アニメーション再生 */
chr_sequence2(o_chr, SEQ_WIN);
chr_sequence2(d_chr, SEQ_LOSE);
return TRUE;
}
else {
play_action(FALSE); /* アニメーション再生 */
chr_sequence2(o_chr, SEQ_NORMAL);
chr_sequence2(d_chr, SEQ_NORMAL);
return FALSE;
}
}
/********************************
行動する
戻り値 決着がついたか
********************************/
static
Bool take_action(void)
{
CHR_PARAM* chr;
ACTION* act;
ATK_TECH* atk;
Bool ret = FALSE;
chr = &chr_param[turn]; /* キャラクタ */
act = chr->action; /* 行動 */
atk = NULL;
if ( act->kind == ACT_ATTACK1 ) { /* 弱攻撃 */
atk = &chr->data->attack1;
}
else if ( act->kind == ACT_ATTACK2 ) { /* 強攻撃 */
atk = &chr->data->attack2;
}
if ( --act->count == 0 ) {
if ( atk == NULL ) {
draw_screen();
}
move_up(act); /* 繰り上げ */
if ( atk ) {
ret = attack(atk); /* 攻撃 */
}
else {
slow_bar(TRUE); /* 行動描画 */
select_action(chr); /* 行動選択 */
}
}
return ret;
}
/************************************
ゲームメイン
引数 chr = キャラクタデータ
opr = 操作
戻り値 TRUE : ゲーム続行
FALSE : 終了
************************************/
static
Bool game_main(CHR_DATA* chr[2], int opr[2])
{
int count, win;
for (count = 0; count < 2; count++) { /* キャラクタ初期化 */
init_chr(&chr_param[count], count, opr[count], chr[count]);
}
play_main_bgm(); /* メインBGM演奏開始 */
draw_start(); /* 初期画面描画 */
turn = PLAYER2; /* ターン */
if ( !ready_chr() ) { /* キャラクタ登場 */
return FALSE;
}
count = 4;
win = 0;
while ( win == 0 ) {
if ( esc_key ) {
return FALSE; /* ゲーム終了 */
}
mode = MODE_BATTLE; /* 戦闘モード */
anim_chr(PLAYER1); /* キャラクタアニメーション */
anim_chr(PLAYER2);
draw_screen(); /* 画面描画 */
if ( --count == 0 ) {
turn ^= 0x01;
if ( take_action() ) { /* 行動 */
break;
}
count = 4;
}
}
return end_battle(turn); /* 戦闘終了 */
}
/************
メイン
************/
int main(int argc, char* argv[])
{
CHR_DATA* chr[2];
int opr[2];
watch = ((argc >= 2) && ((*argv[1] == 'W') || (*argv[1] == 'w')));
/* 観戦モード */
_iocs_tgusemd(0, 2); /* グラフィック画面使用 */
_iocs_tgusemd(1, 2); /* テキスト画面使用 */
_dos_c_curoff(); /* カーソルOFF */
_iocs_crtmod(0x0e); /* 画面モード設定 */
_iocs_g_clr_on(); /* グラフィック画面表示 */
_iocs_b_bpoke((void*)0xe82500, 0x12); /* プライオリティ設定 */
if ( init_screen() ) { /* 画面初期化 */
_iocs_contrast(-2); /* フェードイン */
return 1;
}
if ( init_sound() ) { /* 音源初期化 */
_iocs_contrast(-2); /* フェードイン */
return 1;
}
srand((unsigned int)_iocs_timeget()); /* 乱数初期化 */
while ( 1 ) {
if ( watch ) {
auto_select(chr, opr); /* 自動選択 */
}
else if ( !select(chr, opr) ) { /* モード・キャラクタ選択 */
break;
}
if ( !game_main(chr, opr) ) { /* ゲームメイン */
break;
}
}
stop_music(); /* 演奏停止 */
_iocs_tgusemd(0, 3); /* グラフィック画面使用 */
_iocs_tgusemd(1, 3); /* テキスト画面使用 */
_dos_c_width(0); /* 画面モード設定 */
_dos_c_curon(); /* カーソルON */
_dos_kflushio(0xff); /* キーバッファクリア */
_iocs_contrast(-2); /* フェードイン */
return 0;
}
/****************** End of File ***************************************************/